<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 6.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha256-CTSx/A06dm1B063156EVh15m6Y67pAjZZaQc89LLSrU=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.24/fancybox/fancybox.css" integrity="sha256-vQkngPS8jiHHH0I6ABTZroZk8NPZ7b+MUReOFE9UsXQ=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"rjyblog.gitee.io","root":"/","images":"/images","scheme":"Pisces","darkmode":false,"version":"8.18.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":null},"fold":{"enable":false,"height":500},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="本文详细介绍了缓存拦截器的处理逻辑">
<meta property="og:type" content="article">
<meta property="og:title" content="okhttp详解系列四：缓存拦截器">
<meta property="og:url" content="https://rjyblog.gitee.io/posts/37107c2e.html">
<meta property="og:site_name" content="任建勇的博客">
<meta property="og:description" content="本文详细介绍了缓存拦截器的处理逻辑">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2023-08-17T07:12:30.000Z">
<meta property="article:modified_time" content="2023-09-21T02:47:23.109Z">
<meta property="article:author" content="Jason">
<meta property="article:tag" content="okhttp">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="https://rjyblog.gitee.io/posts/37107c2e.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://rjyblog.gitee.io/posts/37107c2e.html","path":"posts/37107c2e.html","title":"okhttp详解系列四：缓存拦截器"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>okhttp详解系列四：缓存拦截器 | 任建勇的博客</title>
  








  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">任建勇的博客</p>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%BC%93%E5%AD%98%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95"><span class="nav-text">缓存使用方法</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%BC%93%E5%AD%98%E6%8B%A6%E6%88%AA%E5%99%A8%E6%B5%81%E7%A8%8B"><span class="nav-text">缓存拦截器流程</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#CacheStrategy"><span class="nav-text">CacheStrategy</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%93%8D%E5%BA%94%E5%B9%B4%E9%BE%84%E7%9A%84%E8%AE%A1%E7%AE%97%E6%96%B9%E6%B3%95"><span class="nav-text">响应年龄的计算方法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%93%8D%E5%BA%94%E4%BF%9D%E9%B2%9C%E6%9C%9F%E7%9A%84%E8%AE%A1%E7%AE%97%E6%96%B9%E6%B3%95"><span class="nav-text">响应保鲜期的计算方法</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%86%99%E5%85%A5Cache"><span class="nav-text">写入Cache</span></a></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="Jason"
      src="/images/avatar.png">
  <p class="site-author-name" itemprop="name">Jason</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">66</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">13</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">23</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://rjyblog.gitee.io/posts/37107c2e.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="Jason">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="任建勇的博客">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="okhttp详解系列四：缓存拦截器 | 任建勇的博客">
      <meta itemprop="description" content="本文详细介绍了缓存拦截器的处理逻辑">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          okhttp详解系列四：缓存拦截器
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2023-08-17 15:12:30" itemprop="dateCreated datePublished" datetime="2023-08-17T15:12:30+08:00">2023-08-17</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2023-09-21 10:47:23" itemprop="dateModified" datetime="2023-09-21T10:47:23+08:00">2023-09-21</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/okhttp/" itemprop="url" rel="index"><span itemprop="name">okhttp</span></a>
        </span>
    </span>

  
</div>

            <div class="post-description">本文详细介绍了缓存拦截器的处理逻辑</div>
        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><ul>
<li><a href="/posts/78efaca4.html" title="okhttp详解系列一：开篇">okhttp详解系列一：开篇</a></li>
<li><a href="/posts/8e83ed63.html" title="okhttp详解系列二：重试重定向拦截器">okhttp详解系列二：重试重定向拦截器</a></li>
<li><a href="/posts/6e2b1d41.html" title="okhttp详解系列三：桥拦截器 BridgeInterceptor">okhttp详解系列三：桥拦截器 BridgeInterceptor</a></li>
<li><a href="/posts/37107c2e.html" title="okhttp详解系列四：缓存拦截器">okhttp详解系列四：缓存拦截器</a></li>
<li><a href="/posts/ee27d764.html" title="okhttp详解系列五：连接拦截器 ConnectInterceptor">okhttp详解系列五：连接拦截器 ConnectInterceptor</a></li>
<li><a href="/posts/73cf04e1.html" title="okhttp详解系列六：服务请求拦截器 CallServerInterceptor">okhttp详解系列六：服务请求拦截器 CallServerInterceptor</a>

</li>
</ul>
<h2 id="缓存使用方法"><a href="#缓存使用方法" class="headerlink" title="缓存使用方法"></a>缓存使用方法</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">val</span> client: OkHttpClient = OkHttpClient.Builder()</span><br><span class="line">    .cache(Cache(</span><br><span class="line">        directory = File(<span class="string">&quot;/dir/http_cache&quot;</span>),</span><br><span class="line">        maxSize = <span class="number">5L</span> * <span class="number">1024L</span> * <span class="number">1024L</span> <span class="comment">// 5MiB</span></span><br><span class="line">    ))</span><br><span class="line">    .build()</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>缓存机制只实现了get请求的缓存，不支持其他的请求类型，比如POST。下面的官方的说明：</p>
<blockquote>
<p>Don’t cache non-GET responses. We’re technically allowed to cache HEAD requests and some POST requests, but the complexity of doing so is high and the benefit is low.</p>
</blockquote>
<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="311px" preserveAspectRatio="none" style="width:499px;height:311px;background:#FFFFFF;" version="1.1" viewBox="0 0 499 311" width="499px" zoomAndPan="magnify"><defs/><g><!--class Cache--><g id="elem_Cache"><rect codeLine="1" fill="#F1F1F1" height="80.5938" id="Cache" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="311" x="7" y="115"/><ellipse cx="136.25" cy="131" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M138.5938,126.6719 C137.6563,126.2344 137.0625,126.0938 136.1875,126.0938 C133.5625,126.0938 131.5625,128.1719 131.5625,130.8906 L131.5625,132.0156 C131.5625,134.5938 133.6719,136.4844 136.5625,136.4844 C137.7813,136.4844 138.9375,136.1875 139.6875,135.6406 C140.2656,135.2344 140.5938,134.7813 140.5938,134.3906 C140.5938,133.9375 140.2031,133.5469 139.7344,133.5469 C139.5156,133.5469 139.3125,133.625 139.125,133.8125 C138.6719,134.2969 138.6719,134.2969 138.4844,134.3906 C138.0625,134.6563 137.375,134.7813 136.6094,134.7813 C134.5625,134.7813 133.2656,133.6875 133.2656,131.9844 L133.2656,130.8906 C133.2656,129.1094 134.5156,127.7969 136.25,127.7969 C136.8281,127.7969 137.4375,127.9531 137.9063,128.2031 C138.3906,128.4844 138.5625,128.7031 138.6563,129.1094 C138.7188,129.5156 138.75,129.6406 138.8906,129.7656 C139.0313,129.9063 139.2656,130.0156 139.4844,130.0156 C139.75,130.0156 140.0156,129.875 140.1875,129.6563 C140.2969,129.5 140.3281,129.3125 140.3281,128.8906 L140.3281,127.4688 C140.3281,127.0313 140.3125,126.9063 140.2188,126.75 C140.0625,126.4844 139.7813,126.3438 139.4844,126.3438 C139.1875,126.3438 138.9844,126.4375 138.7656,126.75 L138.5938,126.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="44" x="156.75" y="135.8467">Cache</text><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="317" y1="147" y2="147"/><line style="stroke:#181818;stroke-width:0.5;" x1="8" x2="317" y1="155" y2="155"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="244" x="13" y="171.9951">get(request: Request): Response?</text><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="299" x="13" y="188.292">put(response: Response): CacheRequest?</text></g><!--class CacheInterceptor--><g id="elem_CacheInterceptor"><rect fill="#F1F1F1" height="48" id="CacheInterceptor" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="160" x="212.5" y="7"/><ellipse cx="227.5" cy="23" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M229.8438,18.6719 C228.9063,18.2344 228.3125,18.0938 227.4375,18.0938 C224.8125,18.0938 222.8125,20.1719 222.8125,22.8906 L222.8125,24.0156 C222.8125,26.5938 224.9219,28.4844 227.8125,28.4844 C229.0313,28.4844 230.1875,28.1875 230.9375,27.6406 C231.5156,27.2344 231.8438,26.7813 231.8438,26.3906 C231.8438,25.9375 231.4531,25.5469 230.9844,25.5469 C230.7656,25.5469 230.5625,25.625 230.375,25.8125 C229.9219,26.2969 229.9219,26.2969 229.7344,26.3906 C229.3125,26.6563 228.625,26.7813 227.8594,26.7813 C225.8125,26.7813 224.5156,25.6875 224.5156,23.9844 L224.5156,22.8906 C224.5156,21.1094 225.7656,19.7969 227.5,19.7969 C228.0781,19.7969 228.6875,19.9531 229.1563,20.2031 C229.6406,20.4844 229.8125,20.7031 229.9063,21.1094 C229.9688,21.5156 230,21.6406 230.1406,21.7656 C230.2813,21.9063 230.5156,22.0156 230.7344,22.0156 C231,22.0156 231.2656,21.875 231.4375,21.6563 C231.5469,21.5 231.5781,21.3125 231.5781,20.8906 L231.5781,19.4688 C231.5781,19.0313 231.5625,18.9063 231.4688,18.75 C231.3125,18.4844 231.0313,18.3438 230.7344,18.3438 C230.4375,18.3438 230.2344,18.4375 230.0156,18.75 L229.8438,18.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="128" x="241.5" y="27.8467">CacheInterceptor</text><line style="stroke:#181818;stroke-width:0.5;" x1="213.5" x2="371.5" y1="39" y2="39"/><line style="stroke:#181818;stroke-width:0.5;" x1="213.5" x2="371.5" y1="47" y2="47"/></g><!--class DiskLruCache--><g id="elem_DiskLruCache"><rect fill="#F1F1F1" height="48" id="DiskLruCache" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="129" x="98" y="256"/><ellipse cx="113" cy="272" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M115.3438,267.6719 C114.4063,267.2344 113.8125,267.0938 112.9375,267.0938 C110.3125,267.0938 108.3125,269.1719 108.3125,271.8906 L108.3125,273.0156 C108.3125,275.5938 110.4219,277.4844 113.3125,277.4844 C114.5313,277.4844 115.6875,277.1875 116.4375,276.6406 C117.0156,276.2344 117.3438,275.7813 117.3438,275.3906 C117.3438,274.9375 116.9531,274.5469 116.4844,274.5469 C116.2656,274.5469 116.0625,274.625 115.875,274.8125 C115.4219,275.2969 115.4219,275.2969 115.2344,275.3906 C114.8125,275.6563 114.125,275.7813 113.3594,275.7813 C111.3125,275.7813 110.0156,274.6875 110.0156,272.9844 L110.0156,271.8906 C110.0156,270.1094 111.2656,268.7969 113,268.7969 C113.5781,268.7969 114.1875,268.9531 114.6563,269.2031 C115.1406,269.4844 115.3125,269.7031 115.4063,270.1094 C115.4688,270.5156 115.5,270.6406 115.6406,270.7656 C115.7813,270.9063 116.0156,271.0156 116.2344,271.0156 C116.5,271.0156 116.7656,270.875 116.9375,270.6563 C117.0469,270.5 117.0781,270.3125 117.0781,269.8906 L117.0781,268.4688 C117.0781,268.0313 117.0625,267.9063 116.9688,267.75 C116.8125,267.4844 116.5313,267.3438 116.2344,267.3438 C115.9375,267.3438 115.7344,267.4375 115.5156,267.75 L115.3438,267.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="97" x="127" y="276.8467">DiskLruCache</text><line style="stroke:#181818;stroke-width:0.5;" x1="99" x2="226" y1="288" y2="288"/><line style="stroke:#181818;stroke-width:0.5;" x1="99" x2="226" y1="296" y2="296"/></g><!--class CacheStrategy--><g id="elem_CacheStrategy"><rect fill="#F1F1F1" height="48" id="CacheStrategy" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="139" x="353" y="131.5"/><ellipse cx="368" cy="147.5" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M370.3438,143.1719 C369.4063,142.7344 368.8125,142.5938 367.9375,142.5938 C365.3125,142.5938 363.3125,144.6719 363.3125,147.3906 L363.3125,148.5156 C363.3125,151.0938 365.4219,152.9844 368.3125,152.9844 C369.5313,152.9844 370.6875,152.6875 371.4375,152.1406 C372.0156,151.7344 372.3438,151.2813 372.3438,150.8906 C372.3438,150.4375 371.9531,150.0469 371.4844,150.0469 C371.2656,150.0469 371.0625,150.125 370.875,150.3125 C370.4219,150.7969 370.4219,150.7969 370.2344,150.8906 C369.8125,151.1563 369.125,151.2813 368.3594,151.2813 C366.3125,151.2813 365.0156,150.1875 365.0156,148.4844 L365.0156,147.3906 C365.0156,145.6094 366.2656,144.2969 368,144.2969 C368.5781,144.2969 369.1875,144.4531 369.6563,144.7031 C370.1406,144.9844 370.3125,145.2031 370.4063,145.6094 C370.4688,146.0156 370.5,146.1406 370.6406,146.2656 C370.7813,146.4063 371.0156,146.5156 371.2344,146.5156 C371.5,146.5156 371.7656,146.375 371.9375,146.1563 C372.0469,146 372.0781,145.8125 372.0781,145.3906 L372.0781,143.9688 C372.0781,143.5313 372.0625,143.4063 371.9688,143.25 C371.8125,142.9844 371.5313,142.8438 371.2344,142.8438 C370.9375,142.8438 370.7344,142.9375 370.5156,143.25 L370.3438,143.1719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="107" x="382" y="152.3467">CacheStrategy</text><line style="stroke:#181818;stroke-width:0.5;" x1="354" x2="491" y1="163.5" y2="163.5"/><line style="stroke:#181818;stroke-width:0.5;" x1="354" x2="491" y1="171.5" y2="171.5"/></g><!--class CacheControl--><g id="elem_CacheControl"><rect fill="#F1F1F1" height="48" id="CacheControl" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="130" x="357.5" y="256"/><ellipse cx="372.5" cy="272" fill="#ADD1B2" rx="11" ry="11" style="stroke:#181818;stroke-width:1.0;"/><path d="M374.8438,267.6719 C373.9063,267.2344 373.3125,267.0938 372.4375,267.0938 C369.8125,267.0938 367.8125,269.1719 367.8125,271.8906 L367.8125,273.0156 C367.8125,275.5938 369.9219,277.4844 372.8125,277.4844 C374.0313,277.4844 375.1875,277.1875 375.9375,276.6406 C376.5156,276.2344 376.8438,275.7813 376.8438,275.3906 C376.8438,274.9375 376.4531,274.5469 375.9844,274.5469 C375.7656,274.5469 375.5625,274.625 375.375,274.8125 C374.9219,275.2969 374.9219,275.2969 374.7344,275.3906 C374.3125,275.6563 373.625,275.7813 372.8594,275.7813 C370.8125,275.7813 369.5156,274.6875 369.5156,272.9844 L369.5156,271.8906 C369.5156,270.1094 370.7656,268.7969 372.5,268.7969 C373.0781,268.7969 373.6875,268.9531 374.1563,269.2031 C374.6406,269.4844 374.8125,269.7031 374.9063,270.1094 C374.9688,270.5156 375,270.6406 375.1406,270.7656 C375.2813,270.9063 375.5156,271.0156 375.7344,271.0156 C376,271.0156 376.2656,270.875 376.4375,270.6563 C376.5469,270.5 376.5781,270.3125 376.5781,269.8906 L376.5781,268.4688 C376.5781,268.0313 376.5625,267.9063 376.4688,267.75 C376.3125,267.4844 376.0313,267.3438 375.7344,267.3438 C375.4375,267.3438 375.2344,267.4375 375.0156,267.75 L374.8438,267.6719 Z " fill="#000000"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="98" x="386.5" y="276.8467">CacheControl</text><line style="stroke:#181818;stroke-width:0.5;" x1="358.5" x2="486.5" y1="288" y2="288"/><line style="stroke:#181818;stroke-width:0.5;" x1="358.5" x2="486.5" y1="296" y2="296"/></g><!--reverse link CacheInterceptor to Cache--><g id="link_CacheInterceptor_Cache"><path codeLine="5" d="M259.3146,63.2706 C241.4416,80.1126 225.493,95.142 204.49,114.933 " fill="none" id="CacheInterceptor-backto-Cache" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="268.048,55.041,260.9381,56.2447,259.3146,63.2706,266.4245,62.067,268.048,55.041" style="stroke:#181818;stroke-width:1.0;"/></g><!--reverse link Cache to DiskLruCache--><g id="link_Cache_DiskLruCache"><path codeLine="6" d="M162.5,208.272 C162.5,227.9732 162.5,239.0687 162.5,255.8428 " fill="none" id="Cache-backto-DiskLruCache" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="162.5,196.272,158.5,202.272,162.5,208.272,166.5,202.272,162.5,196.272" style="stroke:#181818;stroke-width:1.0;"/></g><!--link CacheInterceptor to CacheStrategy--><g id="link_CacheInterceptor_CacheStrategy"><path codeLine="7" d="M316.952,55.041 C340.047,76.804 370.1452,105.1662 393.3492,127.0312 " fill="none" id="CacheInterceptor-to-CacheStrategy" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="397.716,131.146,393.909,122.0627,394.077,127.717,388.4227,127.885,397.716,131.146" style="stroke:#181818;stroke-width:1.0;"/></g><!--link CacheStrategy to CacheControl--><g id="link_CacheStrategy_CacheControl"><path codeLine="8" d="M422.5,179.541 C422.5,201.304 422.5,227.781 422.5,249.6455 " fill="none" id="CacheStrategy-to-CacheControl" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="422.5,255.6455,426.5,246.6455,422.5,250.6455,418.5,246.6455,422.5,255.6455" style="stroke:#181818;stroke-width:1.0;"/></g><!--SRC=[Iyv9B2vMS4vCpaXLgEPI08Bqr1ADejJ2qjJY4Yk580X34yGgBiZFAqwr1oigA0KfWeWWv83Am2P1TTbprNA1-Pvv9Qb5oQa59Vb52bgwkX1542amtoMpEDkdg1H965c7hguTH4TmIL5YIMfw9HSA3o7ld9zNKfIV0m00]--></g></svg>

<p><strong>Cache-Control</strong>请求头是控制缓存策略的关键，server、client端都可以进行设置。<strong>Cache-Control</strong>决定了哪些response可以被缓存，以及缓存的response是否满足当前的request。协议定义可以参考<a target="_blank" rel="noopener external nofollow noreferrer" href="https://tools.ietf.org/html/rfc7234#section-5.2">RFC 7234, 5.2</a>。</p>
<h2 id="缓存拦截器流程"><a href="#缓存拦截器流程" class="headerlink" title="缓存拦截器流程"></a>缓存拦截器流程</h2><p>缓存拦截器的处理流程如下：</p>
<ol>
<li>首先通过url的md5值去读取本地可用缓存（后面会校验缓存是否可用）；</li>
<li>计算得到CacheStrategy，实际上就是计算得到<strong>networkRequest</strong>和<strong>cacheResponse</strong>，如果两者都为null，就直接报504错误；如果networkRequest是null，表示直接使用缓存。</li>
</ol>
<?xml version="1.0" encoding="us-ascii" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="760px" preserveAspectRatio="none" style="width:741px;height:760px;background:#FFFFFF;" version="1.1" viewBox="0 0 741 760" width="741px" zoomAndPan="magnify"><defs/><g><ellipse cx="248.75" cy="20" fill="#222222" rx="10" ry="10" style="stroke:#222222;stroke-width:1.0;"/><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="131" x="183.25" y="50"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="111" x="193.25" y="71.1387">&#36890;&#36807;url&#35835;&#21462;&#26412;&#22320;&#32531;&#23384;</text><rect fill="#F1F1F1" height="61.9063" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="196" x="150.75" y="103.9688"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="176" x="160.75" y="125.1074">&#35745;&#31639;&#24471;&#21040;CacheStrategy&#65292;&#21253;&#21547;:</text><ellipse cx="166.25" cy="134.4063" fill="#000000" rx="2.5" ry="2.5" style="stroke:#000000;stroke-width:0.0;"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="98" x="172.75" y="139.0762">networkRequest</text><ellipse cx="166.25" cy="148.375" fill="#000000" rx="2.5" ry="2.5" style="stroke:#000000;stroke-width:0.0;"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="96" x="172.75" y="153.0449">cacheResponse</text><polygon fill="#F1F1F1" points="166.75,185.875,330.75,185.875,342.75,198.6797,330.75,211.4844,166.75,211.4844,154.75,198.6797,166.75,185.875" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="160" x="166.75" y="196.0854">networkRequest == null &amp;&amp;</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="136" x="166.75" y="208.8901">cacheResponse == null</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="21" x="133.75" y="196.0854">yes</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="14" x="342.75" y="196.0854">no</text><rect fill="#F1F1F1" height="47.9375" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="166" x="11" y="221.4844"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="146" x="21" y="242.623">only-if-cached&#22330;&#26223;&#65292;&#20294;&#26159;</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="120" x="21" y="256.5918">&#32531;&#23384;&#19981;&#21512;&#27861;&#65292;&#19978;&#25253;504</text><polygon fill="#F1F1F1" points="334.5,221.4844,472.5,221.4844,484.5,233.4844,472.5,245.4844,334.5,245.4844,322.5,233.4844,334.5,221.4844" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="138" x="334.5" y="237.2925">networkRequest == null</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="21" x="301.5" y="230.8901">yes</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="14" x="484.5" y="230.8901">no</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="207" y="255.4844"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="96" x="217" y="276.623">&#20351;&#29992;&#32531;&#23384;&#21709;&#24212;&#35831;&#27714;</text><rect fill="#F1F1F1" height="47.9375" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="214" x="435" y="255.4844"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="168" x="445" y="276.623">&#20351;&#29992;&#19979;&#19968;&#20010;&#25318;&#25130;&#22120;&#22788;&#29702;&#32593;&#32476;&#35831;&#27714;</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="194" x="445" y="290.5918">chain.proceed(networkRequest)</text><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="484" y="371.8242"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="96" x="494" y="392.9629">&#36825;&#26159;&#19968;&#20010;&#26465;&#20214;&#35831;&#27714;</text><polygon fill="#F1F1F1" points="463,425.793,621,425.793,633,437.793,621,449.793,463,449.793,451,437.793,463,425.793" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="158" x="463" y="441.6011">&#21709;&#24212;&#30721;&#26159;304&#65288;Not Modified&#65289;</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="21" x="430" y="435.1987">yes</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="14" x="633" y="435.1987">no</text><rect fill="#F1F1F1" height="47.9375" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="156" x="363" y="459.793"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="136" x="373" y="480.9316">&#21512;&#24182;&#32593;&#32476;&#35831;&#27714;&#21644;&#26412;&#22320;&#32531;&#23384;,</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="108" x="373" y="494.9004">&#19981;&#38656;&#35201;&#26356;&#26032;&#26412;&#22320;&#32531;&#23384;</text><ellipse cx="441" cy="538.7305" fill="none" rx="11" ry="11" style="stroke:#222222;stroke-width:1.0;"/><ellipse cx="441" cy="538.7305" fill="#222222" rx="6" ry="6" style="stroke:#222222;stroke-width:1.0;"/><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="116" x="585" y="459.793"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="96" x="595" y="480.9316">&#37322;&#25918;&#26412;&#22320;&#32531;&#23384;&#36164;&#28304;</text><polygon fill="#F1F1F1" points="476,323.4219,608,323.4219,620,335.4219,608,347.4219,476,347.4219,464,335.4219,476,323.4219" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="21" x="546" y="357.6323">yes</text><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="132" x="476" y="339.23">cacheResponse != null</text><polygon fill="#F1F1F1" points="542,569.7305,554,581.7305,542,593.7305,530,581.7305,542,569.7305" style="stroke:#181818;stroke-width:0.5;"/><rect fill="#F1F1F1" height="33.9688" rx="12.5" ry="12.5" style="stroke:#181818;stroke-width:0.5;" width="68" x="508" y="613.7305"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="48" x="518" y="634.8691">&#20445;&#23384;&#32531;&#23384;</text><polygon fill="#F1F1F1" points="403.5,653.6992,415.5,665.6992,403.5,677.6992,391.5,665.6992,403.5,653.6992" style="stroke:#181818;stroke-width:0.5;"/><polygon fill="#F1F1F1" points="248.75,683.6992,260.75,695.6992,248.75,707.6992,236.75,695.6992,248.75,683.6992" style="stroke:#181818;stroke-width:0.5;"/><ellipse cx="248.75" cy="738.6992" fill="none" rx="11" ry="11" style="stroke:#222222;stroke-width:1.0;"/><ellipse cx="248.75" cy="738.6992" fill="#222222" rx="6" ry="6" style="stroke:#222222;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="248.75" x2="248.75" y1="30" y2="50"/><polygon fill="#181818" points="244.75,40,248.75,50,252.75,40,248.75,44" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="248.75" x2="248.75" y1="83.9688" y2="103.9688"/><polygon fill="#181818" points="244.75,93.9688,248.75,103.9688,252.75,93.9688,248.75,97.9688" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="441" x2="441" y1="507.7305" y2="527.7305"/><polygon fill="#181818" points="437,517.7305,441,527.7305,445,517.7305,441,521.7305" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="451" x2="441" y1="437.793" y2="437.793"/><line style="stroke:#181818;stroke-width:1.0;" x1="441" x2="441" y1="437.793" y2="459.793"/><polygon fill="#181818" points="437,449.793,441,459.793,445,449.793,441,453.793" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="633" x2="643" y1="437.793" y2="437.793"/><line style="stroke:#181818;stroke-width:1.0;" x1="643" x2="643" y1="437.793" y2="459.793"/><polygon fill="#181818" points="639,449.793,643,459.793,647,449.793,643,453.793" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="643" x2="643" y1="493.7617" y2="554.7305"/><line style="stroke:#181818;stroke-width:1.0;" x1="643" x2="542" y1="554.7305" y2="554.7305"/><line style="stroke:#181818;stroke-width:1.0;" x1="542" x2="542" y1="554.7305" y2="569.7305"/><polygon fill="#181818" points="538,559.7305,542,569.7305,546,559.7305,542,563.7305" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="542" x2="542" y1="405.793" y2="425.793"/><polygon fill="#181818" points="538,415.793,542,425.793,546,415.793,542,419.793" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="542" x2="542" y1="347.4219" y2="371.8242"/><polygon fill="#181818" points="538,361.8242,542,371.8242,546,361.8242,542,365.8242" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="620" x2="715" y1="335.4219" y2="335.4219"/><polygon fill="#181818" points="711,453.7773,715,463.7773,719,453.7773,715,457.7773" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="715" x2="715" y1="335.4219" y2="581.7305"/><line style="stroke:#181818;stroke-width:1.0;" x1="715" x2="554" y1="581.7305" y2="581.7305"/><polygon fill="#181818" points="564,577.7305,554,581.7305,564,585.7305,560,581.7305" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="542" x2="542" y1="303.4219" y2="323.4219"/><polygon fill="#181818" points="538,313.4219,542,323.4219,546,313.4219,542,317.4219" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="542" x2="542" y1="593.7305" y2="613.7305"/><polygon fill="#181818" points="538,603.7305,542,613.7305,546,603.7305,542,607.7305" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="322.5" x2="265" y1="233.4844" y2="233.4844"/><line style="stroke:#181818;stroke-width:1.0;" x1="265" x2="265" y1="233.4844" y2="255.4844"/><polygon fill="#181818" points="261,245.4844,265,255.4844,269,245.4844,265,249.4844" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="484.5" x2="542" y1="233.4844" y2="233.4844"/><line style="stroke:#181818;stroke-width:1.0;" x1="542" x2="542" y1="233.4844" y2="255.4844"/><polygon fill="#181818" points="538,245.4844,542,255.4844,546,245.4844,542,249.4844" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="265" x2="265" y1="289.4531" y2="665.6992"/><line style="stroke:#181818;stroke-width:1.0;" x1="265" x2="391.5" y1="665.6992" y2="665.6992"/><polygon fill="#181818" points="381.5,661.6992,391.5,665.6992,381.5,669.6992,385.5,665.6992" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="542" x2="542" y1="647.6992" y2="665.6992"/><line style="stroke:#181818;stroke-width:1.0;" x1="542" x2="415.5" y1="665.6992" y2="665.6992"/><polygon fill="#181818" points="425.5,661.6992,415.5,665.6992,425.5,669.6992,421.5,665.6992" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="154.75" x2="94" y1="198.6797" y2="198.6797"/><line style="stroke:#181818;stroke-width:1.0;" x1="94" x2="94" y1="198.6797" y2="221.4844"/><polygon fill="#181818" points="90,211.4844,94,221.4844,98,211.4844,94,215.4844" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="342.75" x2="403.5" y1="198.6797" y2="198.6797"/><line style="stroke:#181818;stroke-width:1.0;" x1="403.5" x2="403.5" y1="198.6797" y2="221.4844"/><polygon fill="#181818" points="399.5,211.4844,403.5,221.4844,407.5,211.4844,403.5,215.4844" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="94" x2="94" y1="269.4219" y2="695.6992"/><line style="stroke:#181818;stroke-width:1.0;" x1="94" x2="236.75" y1="695.6992" y2="695.6992"/><polygon fill="#181818" points="226.75,691.6992,236.75,695.6992,226.75,699.6992,230.75,695.6992" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="403.5" x2="403.5" y1="677.6992" y2="695.6992"/><line style="stroke:#181818;stroke-width:1.0;" x1="403.5" x2="260.75" y1="695.6992" y2="695.6992"/><polygon fill="#181818" points="270.75,691.6992,260.75,695.6992,270.75,699.6992,266.75,695.6992" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="248.75" x2="248.75" y1="165.875" y2="185.875"/><polygon fill="#181818" points="244.75,175.875,248.75,185.875,252.75,175.875,248.75,179.875" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="248.75" x2="248.75" y1="707.6992" y2="727.6992"/><polygon fill="#181818" points="244.75,717.6992,248.75,727.6992,252.75,717.6992,248.75,721.6992" style="stroke:#181818;stroke-width:1.0;"/><!--SRC=[TPBBJi9058RtVOgw8M34cAYRDgvSwmAtR0WCqjXCiHrYsA51HOI8YXUq998e8QY0KR5oVPdEjAnu1GSAGhtCefdf-S__VtCo2lB9Y66uNkp6x1v6PD6iDl799L6Vi5epMkVu-PfdEBDIC2fNk7E54xLLdpy4Df3iGs0psc-bS6eVPnuvBvo50Er8yfO7R4U0WkWF_q3g0KfOWWhW6I7ej4lObHKMHaIHTJXOBxIfnoKNYq80EgD0SJ4iNPm4nQXR2Bg7wW1M6oHNfHHw-u1SLxtGGjQrDCuaoEl5eA8bIV9XUM69Pu2e02UK1ax_ilmArDjT8rkoVF5v6ZUoPlM3lEpnj3nb-AtKjMDTY-bQcHmNIQACSoLy7pSo1qRxr6YgLY-zRCWdmFcmBFa12Fn0SV53Fufe7ydCtuGqsUpcwEr7iVc2tgnF64TM5hfnjqk5YmjB_LPYNKBicXGGWW88z5j7lssfCPqY_gnFe-EprFJZcFD2EkoU6ZEBk-JsZLpMx4zdxAGWAJmws8OsJEaT9acsCzreliT98pDk1v1IClOTftVpL3Z9iKhMTv3s1G00]--></g></svg>

<h2 id="CacheStrategy"><a href="#CacheStrategy" class="headerlink" title="CacheStrategy"></a>CacheStrategy</h2><p>CacheStrategy的生成使用的条件比较多，比如request CacheControl、response CacheControl、条件请求等，这块就不详细介绍了。其中要计算响应的年龄和响应的保鲜期，下面详细介绍两者的计算方法。</p>
<h3 id="响应年龄的计算方法"><a href="#响应年龄的计算方法" class="headerlink" title="响应年龄的计算方法"></a>响应年龄的计算方法</h3><p>响应的年龄是自它生成<small>（或者通过源服务器成功验证）</small>之后所经过的时长，计算方法如下：</p>
<ul>
<li>第一步：计算原始响应时长，”接收到响应的时间” 减去 “响应的服务时间”（表示生成该response的时间，响应头中的Date字段，如果没有，则取接收到响应的时间）</small>，得到的时间差与<strong>Age</strong>字段进行比较，取最大值；</li>
<li>第二步：计算响应时长，“接收到响应的时间”减去“发送响应的时间”；</li>
<li>第三步：计算本地年龄<small>（被缓存的response在本地的保存时长）</small>，当前时间减去接收到response的时间；</li>
<li>最后，把上述三者加和就得到了响应的最终年龄；</li>
</ul>
<p>响应头的Age字段有必要解释一下：如果存在Age字段，则表示这个response是基于缓存生成的，来自缓存服务器，而不是来自原始服务器。所以Age表示该次响应到源服务器提供服务的时间差。</p>
<h3 id="响应保鲜期的计算方法"><a href="#响应保鲜期的计算方法" class="headerlink" title="响应保鲜期的计算方法"></a>响应保鲜期的计算方法</h3><p>一个被缓存的response，如果超过了保鲜期，就表示这个被缓存的response必须再次通过源服务器的验证后才能继续使用；还在保鲜期内的response就可以不经过源服务器的验证就能使用。</p>
<ul>
<li>如果response Cache-Control中指定了max-age<small>（<em>单位秒</em>）</small>，保鲜期就取max-age的值。</li>
<li>如果没有max-age，被缓存响应中指定了Expires<small>（<em>时钟时间</em>）</small>，则保鲜期就是Expires减去响应服务时间<small>（响应头中的Date字段，如果没有则取接收到响应的时间）</small>后得到时间差。</li>
<li>如果Expires也没有，被缓存响应中存在Last-Modified响应头，则保鲜期就是服务时间<small>（如果没有就使用请求发送的时间）</small>减去Last-Modified的时间差的**10%**。</li>
<li>如果上述信息都没有就默认是0。</li>
<li>最后，上述计算得到的保鲜期与request Cache-Control的max-age的值进行比较，取小值。</li>
</ul>
<p>Request Cache-Control中还有两个字段会影响保鲜期的时长：</p>
<ol>
<li><strong>max-stale</strong> 是client端额外给保鲜期增加的时长，就像有的人比较节省，买的东西刚过了保鲜期没几天，就认为还可以继续用，再多用几天。</li>
<li><strong>min-fresh</strong> 是client端给保鲜期减掉的时长，就好比有的人比较讲究，买的食品马上就到保质期了（实际还差几天）就不想吃了。</li>
</ol>
<p>所以，最终计算的保鲜期还要加上<strong>max-stale</strong>，再减去<strong>min-fresh</strong>。</p>
<h2 id="写入Cache"><a href="#写入Cache" class="headerlink" title="写入Cache"></a>写入Cache</h2><p>这块逻辑相对比较简单。</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">internal</span> <span class="function"><span class="keyword">fun</span> <span class="title">put</span><span class="params">(response: <span class="type">Response</span>)</span></span>: CacheRequest? &#123;</span><br><span class="line">  <span class="keyword">val</span> requestMethod = response.request.method</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (HttpMethod.invalidatesCache(response.request.method)) &#123;</span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      remove(response.request)</span><br><span class="line">    &#125; <span class="keyword">catch</span> (_: IOException) &#123;</span><br><span class="line">      <span class="comment">// The cache cannot be written.</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//如果不是GET请求，则不缓存</span></span><br><span class="line">  <span class="keyword">if</span> (requestMethod != <span class="string">&quot;GET&quot;</span>) &#123;</span><br><span class="line">    <span class="comment">// Don&#x27;t cache non-GET responses. We&#x27;re technically allowed to cache HEAD requests and some</span></span><br><span class="line">    <span class="comment">// POST requests, but the complexity of doing so is high and the benefit is low.</span></span><br><span class="line">    <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//如果Vary响应头中包含*则不缓存</span></span><br><span class="line">  <span class="keyword">if</span> (response.hasVaryAll()) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">val</span> entry = Entry(response)</span><br><span class="line">  <span class="keyword">var</span> editor: DiskLruCache.Editor? = <span class="literal">null</span></span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="comment">//使用url的md5作为key获取一个editer</span></span><br><span class="line">    editor = cache.edit(key(response.request.url)) ?: <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line">    <span class="comment">//把response写入到缓存，会把发送时间戳和收到响应的时间戳都写到缓存里面，获取的时候会用来校验</span></span><br><span class="line">    entry.writeTo(editor)</span><br><span class="line">    <span class="keyword">return</span> RealCacheRequest(editor)</span><br><span class="line">  &#125; <span class="keyword">catch</span> (_: IOException) &#123;</span><br><span class="line">    abortQuietly(editor)</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

    </div>

    
    
    

    <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/okhttp/" rel="tag"># okhttp</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/posts/78efaca4.html" rel="prev" title="okhttp详解系列一：开篇">
                  <i class="fa fa-angle-left"></i> okhttp详解系列一：开篇
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/posts/6e2b1d41.html" rel="next" title="okhttp详解系列三：桥拦截器 BridgeInterceptor">
                  okhttp详解系列三：桥拦截器 BridgeInterceptor <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 
    <span itemprop="copyrightYear">2024</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">Jason</span>
  </div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener external nofollow noreferrer" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/pisces/" rel="noopener external nofollow noreferrer" target="_blank">NexT.Pisces</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.24/fancybox/fancybox.umd.js" integrity="sha256-oyhjPiYRWGXaAt+ny/mTMWOnN1GBoZDUQnzzgC7FRI4=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>


  <script class="next-config" data-name="mermaid" type="application/json">{"enable":true,"theme":{"light":"default","dark":"dark"},"js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.5.0/mermaid.min.js","integrity":"sha256-K7oJiQlDulzl24ZUFOywuYme1JqBBvQzK6m8qHjt9Gk="}}</script>
  <script type="module" src="/js/zenuml-definition-074a43fa.js"></script>
  <script type="module" src="/js/mermaid-zenuml.esm.min.mjs"></script>
  <script src="/js/third-party/tags/mermaid.js"></script>


  <script src="/js/third-party/fancybox.js"></script>



  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>



</body>
</html>
